/*
 * Copyright 2008-2012, David George, Licensed under the Apache License,
 * Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.magneato.utils;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.magneato.dto.MagUser;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * Velocity authorization object
 * 
 * @author macwire
 */
public class Authorize {
	/**
	 * Get the username of the user
	 * 
	 * @return the username of the user
	 */
	public static String getPrincipal() {

		Authentication auth = SecurityContextHolder.getContext()
				.getAuthentication();
		if (auth != null) {
			Object obj = auth.getPrincipal();
			if (obj instanceof UserDetails) {
				return ((UserDetails) obj).getUsername();
			}
		}

		return "guest";
	}

	/**
	 * @return The screenname of the user, this saves exposing the real username
	 *         which can be useful to crackers
	 */
	public static String getScreenname() {

		Authentication auth = SecurityContextHolder.getContext()
				.getAuthentication();
		if (auth != null) {
			Object obj = auth.getPrincipal();
			if (obj instanceof MagUser) {
				return ((MagUser) obj).getScreenname();
			}
		}

		return "guest";
	}

	/**
	 * @return UserDetails object of the connected user or null if guest
	 */
	public static MagUser getUserDetails() {

		Authentication auth = SecurityContextHolder.getContext()
				.getAuthentication();
		if (auth != null) {
			Object obj = auth.getPrincipal();
			if (obj instanceof MagUser) {
				return (MagUser) obj;
			}
		}

		return null;
	}

	/**
	 * Find the principal (first) group for the user
	 * 
	 * @return Principal Group
	 */
	public static String getPrincipalGroup() {
		String group = null;

		Authentication auth = SecurityContextHolder.getContext()
				.getAuthentication();
		if (auth != null) {
			Object obj = auth.getPrincipal();
			if (obj instanceof UserDetails) {
				UserDetails ud = (UserDetails) obj;

				Collection<? extends GrantedAuthority> authorities = ud.getAuthorities();

				for (GrantedAuthority authority : authorities) {
					group = authority.getAuthority();
					if (!group.startsWith("ROLE_")) {
						break;
					}
				}// for
			}
		}
		return group;
	}

	/**
	 * Is the user granted all of the supplied roles
	 * 
	 * @param roles
	 *            a string array of roles
	 * @return true if user has all of the listed roles, otherwise false
	 */
	public static boolean allGranted(String[] roles) {
		Set<String> userRoles = getUserRoles();
		for (String role : roles) {
			if (userRoles.contains(role))
				continue;
			return false;
		}
		return true;
	}

	/**
	 * Is the user granted any of the supplied roles
	 * 
	 * @param roles
	 *            a string array of roles
	 * @return true if user has any of the listed roles, otherwise false
	 */
	public static boolean anyGranted(String[] roles) {
		Set<String> userRoles = getUserRoles();
		for (String role : roles) {
			if (userRoles.contains(role))
				return true;
		}
		return false;
	}

	/**
	 * is the user granted none of the supplied roles
	 * 
	 * @param roles
	 *            a string array of roles
	 * @return true only if none of listed roles are granted
	 */
	public static boolean noneGranted(String[] roles) {
		Set<String> userRoles = getUserRoles();
		for (String role : roles) {
			if (userRoles.contains(role))
				return false;
		}
		return true;
	}

	public static Set<String> getUserRoles() {
		Object obj = SecurityContextHolder.getContext().getAuthentication()
				.getPrincipal();
		Set<String> roles = new HashSet<String>();
		if (obj instanceof UserDetails) {
			Collection<? extends GrantedAuthority> gas = ((UserDetails) obj)
					.getAuthorities();
			for (GrantedAuthority ga : gas) {
				roles.add(ga.getAuthority());
			}
		}
		return roles;
	}
}
